#include "gb28181_manager.h"
#include "gb28181_service.h"
#include "utils_log.h"
#include <nlohmann/json.hpp>
#include <iostream>
#include <sstream>
#include <fstream>
#include <algorithm>

using json = nlohmann::json;

namespace El {
namespace GB28181 {

GB28181Manager &GB28181Manager::GetInstance()
{
    static GB28181Manager instance;
    return instance;
}

bool GB28181Manager::Initialize()
{
    if (initialized_) {
        EL_INFO("GB28181Manager already initialized");
        return true;
    }

    EL_INFO("Initializing GB28181Manager...");

    // 注册配置变更监听
    RegisterConfigListener();

    // 获取配置并启动服务
    if (!LoadConfig()) {
        EL_ERROR("Failed to load GB28181 configuration");
        return false;
    }

    if (!StartServices()) {
        EL_ERROR("Failed to start GB28181 services");
        return false;
    }

    initialized_ = true;
    EL_INFO("GB28181Manager ready with {} services", services_.size());

    return true;
}

void GB28181Manager::Shutdown()
{
    if (!initialized_) {
        EL_DEBUG("GB28181Manager not initialized, skipping shutdown");
        return;
    }

    EL_INFO("Shutting down GB28181Manager");

    // 停止所有服务
    StopServices();

    // 取消注册配置监听
    UnregisterConfigListener();

    initialized_ = false;
    EL_INFO("GB28181Manager shutdown complete");
}

bool GB28181Manager::LoadConfig()
{
    auto &configManager = El::Common::ConfigManager::GetInstance();
    nlohmann::json gb28181Config = configManager.GetConfig("/gb28181");

    if (gb28181Config.is_null()) {
        EL_ERROR("GB28181 configuration not found in ConfigManager");
        return false;
    }

    EL_DEBUG("Raw GB28181 configuration: {}", gb28181Config.dump(2));

    bool enabled = true;
    nlohmann::json server_list;
    if (!NormalizeConfig(gb28181Config, server_list, enabled)) {
        EL_ERROR("Failed to normalize GB28181 configuration");
        return false;
    }

    module_enabled_ = enabled;
    current_raw_config_ = gb28181Config;
    current_config_ = server_list;

    EL_INFO("Loaded GB28181 config with module_enabled={}, server count={}", module_enabled_, current_config_.size());

    for (size_t i = 0; i < current_config_.size(); ++i) {
        const auto &serviceConfig = current_config_[i];
        EL_DEBUG("Service {}: server_ip={}, server_port={}, device_id={}, enabled={}", i,
                 serviceConfig.value("server_ip", "N/A"), serviceConfig.value("server_port", 0),
                 serviceConfig.value("device_id", "N/A"), serviceConfig.value("enabled", true));
    }

    return true;
}

void GB28181Manager::RegisterConfigListener()
{
    auto &configManager = El::Common::ConfigManager::GetInstance();

    // 注册GB28181配置变更监听
    config_listener_id_ = configManager.Register(
        "/gb28181", [this](const nlohmann::json &config) -> bool { return OnConfigChanged(config); },
        El::Common::ConfigPriority::APPLY);

    EL_INFO("GB28181 configuration listener registered");
}

void GB28181Manager::UnregisterConfigListener()
{
    if (config_listener_id_ != -1) {
        auto &configManager = El::Common::ConfigManager::GetInstance();
        configManager.Unregister("/gb28181", config_listener_id_);
        config_listener_id_ = -1;
        EL_INFO("GB28181 configuration listener unregistered");
    }
}

bool GB28181Manager::OnConfigChanged(const nlohmann::json &config)
{
    EL_INFO("GB28181 configuration changed, restarting services");
    if (!current_raw_config_.is_null()) {
        EL_DEBUG("Old config: {}", current_raw_config_.dump(2));
    }
    EL_DEBUG("New config: {}", config.dump(2));

    try {
        bool enabled = true;
        nlohmann::json server_list;
        if (!NormalizeConfig(config, server_list, enabled)) {
            EL_ERROR("New GB28181 configuration is invalid");
            return false;
        }

        module_enabled_ = enabled;
        current_raw_config_ = config;
        current_config_ = server_list;

        EL_INFO("Configuration validation passed, module_enabled={}, {} server(s) configured", module_enabled_,
                current_config_.size());

        if (!StartServices()) {
            EL_ERROR("Failed to restart GB28181 services with new configuration");
        }

        EL_INFO("GB28181 services restarted successfully");
        return true;
    } catch (const std::exception &e) {
        EL_ERROR("Exception handling GB28181 configuration change: {}", e.what());
        return false;
    }
}

bool GB28181Manager::StartServices()
{
    if (!module_enabled_) {
        EL_INFO("GB28181 module disabled, stopping any running services");
        StopServices();
        return true;
    }

    if (!current_config_.is_array()) {
        EL_ERROR("Invalid GB28181 configuration format, expected array but got: {}", current_config_.type_name());
        return false;
    }

    EL_INFO("Starting GB28181 services with {} configured server(s)", current_config_.size());

    // 停止现有服务
    StopServices();

    int enabled_count = 0;
    int disabled_count = 0;
    int failed_count = 0;

    // 为每个配置创建服务
    for (size_t i = 0; i < current_config_.size(); ++i) {
        const auto &serviceConfig = current_config_[i];

        // 检查服务配置是否启用
        if (serviceConfig.contains("enabled") && !serviceConfig["enabled"].get<bool>()) {
            EL_INFO("GB28181 service {} is disabled, skipping", i);
            disabled_count++;
            continue;
        }

        if (!CreateService(serviceConfig, static_cast<int>(i))) {
            EL_ERROR("Failed to create GB28181 service {}", i);
            failed_count++;
            // 继续创建其他服务，不因为一个失败而全部失败
        } else {
            enabled_count++;
        }
    }

    if (services_.empty()) {
        EL_WARN("No GB28181 services created");
        return true;
    }

    EL_INFO("Started {} GB28181 service(s)", services_.size());
    return true;
}

void GB28181Manager::StopServices()
{
    if (services_.empty()) {
        return;
    }

    EL_INFO("Stopping {} GB28181 service(s)", services_.size());

    for (auto &service : services_) {
        if (service) {
            service->Stop();
        }
    }

    services_.clear();
    EL_INFO("All GB28181 services stopped");
}

bool GB28181Manager::CreateService(const nlohmann::json &serviceConfig, int index)
{
    EL_DEBUG("Creating GB28181 service {} with config: {}", index, serviceConfig.dump(2));
    try {
        // 验证必需的配置字段
        if (!serviceConfig.contains("server_ip") || !serviceConfig.contains("server_port") ||
            !serviceConfig.contains("device_id")) {
            EL_ERROR("Missing required configuration for GB28181 service {}", index);
            return false;
        }

        // 创建服务实例
        auto service = std::make_shared<GB28181Service>();

        // 初始化服务
        if (!service->Initialize(serviceConfig, index)) {
            EL_ERROR("Failed to initialize GB28181 service {}", index);
            return false;
        }

        // 启动服务
        if (!service->Start()) {
            EL_ERROR("Failed to start GB28181 service {}", index);
            return false;
        }

        services_.push_back(service);
        EL_INFO("GB28181 service {} created successfully for server: {}", index,
                serviceConfig["server_ip"].get<std::string>());

        return true;
    } catch (const std::exception &e) {
        EL_ERROR("Exception creating GB28181 service {}: {}", index, e.what());
        return false;
    }
}

bool GB28181Manager::IsServiceRunning(int service_index) const
{
    if (service_index == -1) {
        // 检查是否有任何服务在运行
        for (const auto &service : services_) {
            if (service && service->IsRunning()) {
                return true;
            }
        }
        return false;
    }

    // 检查特定服务是否在运行
    if (service_index >= 0 && service_index < static_cast<int>(services_.size())) {
        const auto &service = services_[service_index];
        return service && service->IsRunning();
    }

    return false;
}

std::string GB28181Manager::GetConfig() const
{
    const nlohmann::json &config_to_dump = current_raw_config_.is_null() ? current_config_ : current_raw_config_;
    std::string config_str = config_to_dump.dump(4);
    EL_DEBUG("Returning GB28181 config (size: {} bytes): {}", config_str.length(), config_str);
    return config_str;
}

bool GB28181Manager::NormalizeConfig(const nlohmann::json &config, nlohmann::json &out_servers, bool &enabled) const
{
    enabled = true;
    out_servers = nlohmann::json::array();

    if (config.is_null()) {
        EL_ERROR("GB28181 configuration is null");
        return false;
    }

    if (config.is_array()) {
        out_servers = config;
        return true;
    }

    if (config.is_object()) {
        if (config.contains("enabled")) {
            try {
                enabled = config.at("enabled").get<bool>();
            } catch (const std::exception &e) {
                EL_WARN("Failed to parse GB28181 'enabled' flag: {}", e.what());
            }
        }

        if (config.contains("sip_server")) {
            const auto &sip_server = config.at("sip_server");
            if (sip_server.is_array()) {
                out_servers = sip_server;
                return true;
            }
            EL_ERROR("GB28181 'sip_server' field is not an array (type={})", sip_server.type_name());
            return false;
        }

        // 没有 sip_server 字段时，认为没有任何服务器配置
        out_servers = nlohmann::json::array();
        return true;
    }

    EL_ERROR("Unsupported GB28181 configuration type: {}", config.type_name());
    return false;
}

DeviceStatus GB28181Manager::GetDeviceStatus(int server_index) const
{
    if (server_index >= 0 && server_index < static_cast<int>(services_.size())) {
        const auto &service = services_[server_index];
        if (service) {
            return service->GetDeviceStatus();
        }
    }

    return DeviceStatus::OFFLINE;
}

std::string GB28181Manager::GetStatusString(DeviceStatus status) const
{
    switch (status) {
        case DeviceStatus::REGISTERED:
            return "REGISTERED";
        case DeviceStatus::OFFLINE:
            return "OFFLINE";
        case DeviceStatus::REGISTERING:
            return "REGISTERING";
        case DeviceStatus::HEARTBEAT_TIMEOUT:
            return "HEARTBEAT_TIMEOUT";
        case DeviceStatus::ERROR:
            return "ERROR";
        default:
            return "UNKNOWN";
    }
}

} // namespace GB28181
} // namespace El
